import java.util.*;

class AggregateGarden extends Garden{

    private List<Garden> _childGardens;
    public AggregateGarden() {
        _childGardens = new ArrayList<Garden>();
    }

    public void maintainGarden() {
        //ADD CODE to maintain all child gardens in a depth-first traversal order
        Stack<Garden> stack = new Stack<>();
        stack.add(this);

        while (!stack.isEmpty()) {
            Garden garden = stack.pop();

            if (garden instanceof AggregateGarden) {
                List<Garden> gardens = ((AggregateGarden) garden)._childGardens;
                for (int i = gardens.size()-1; i >=0 ; i--) {
                    stack.add(gardens.get(i));
                }
            }
            System.out.println("The garden being maintained is a "+garden.getClass().getSimpleName());
        }
    }
    public boolean addGarden(Garden garden) {
        if (_childGardens.size() == 3) {
            return false;
        }

        if (garden instanceof AggregateGarden) {
            for (Garden gardenTmp : _childGardens) {
                if (gardenTmp instanceof AggregateGarden) {
                    return false;
                }
            }
        }

        _childGardens.add(garden);
        garden.setParent(this);

        return true;
    }
    public boolean removeGarden(Garden garden) {
        if(_childGardens.size()>0) {
            _childGardens.remove(garden);
            garden.setParent(null);
        }
        return false;
    }
    public List<Garden> getChildren(){
        return _childGardens;
    }
}

class TerminalGarden extends Garden{
    public void maintainGarden() {
        System.out.println("The garden being maintained is a "+getClass().getSimpleName());
    }
}

abstract class Garden {
    private Garden _parent = null;
    public abstract void maintainGarden();
    public Garden getParent() {
        return _parent;
    }
    protected void setParent(Garden parent) {
        _parent = parent;
    }
}

public class GardenDemo{
    public static void main(String[] args){
        //Use this method for test code
//        AggregateGarden g1 = new AggregateGarden();
//        AggregateGarden g2 = new AggregateGarden();
//        Garden g3 = new TerminalGarden();
//        Garden g4 = new TerminalGarden();
//        Garden g5 = new TerminalGarden();
//        Garden g6 = new AggregateGarden();
//        g2.addGarden(g4);
//        g1.addGarden(g2);
//        g1.addGarden(g3);
//        System.out.println(g1.addGarden(g5));
//        System.out.println(g1.addGarden(g6));

        AggregateGarden g1 = new AggregateGarden();
        AggregateGarden g2 = new AggregateGarden();
        Garden g3 = new TerminalGarden();
        Garden g4 = new TerminalGarden();
        Garden g5 = new TerminalGarden();
        AggregateGarden g6 = new AggregateGarden();

        g6.addGarden(g5);
        g2.addGarden(g6);
        g2.addGarden(g4);
        g1.addGarden(g2);
        g1.addGarden(g3);

        g1.maintainGarden(); //depth-first traversal g1->g2->g6->g5->g4>g3
    }
}